﻿using log4net;

namespace System.Web.Mvc
{
	public class CustomHandleErrorAttribute : HandleErrorAttribute
	{
		#region Fields
		private readonly ILog _logger; 
		#endregion

		#region .ctor
		/// <summary>
		/// Initializes a new instance of the <see cref="CustomHandleErrorAttribute"/> class.
		/// </summary>
		public CustomHandleErrorAttribute()
		{
			_logger = LogManager.GetLogger("Portal");
		} 
		#endregion

		#region Methods
		/// <summary>
		/// Called when an exception occurs.
		/// </summary>
		/// <param name="filterContext">The action-filter context.</param>
		public override void OnException(ExceptionContext filterContext)
		{
			if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
			{
				return;
			}

			if (new HttpException(null, filterContext.Exception).GetHttpCode() != 500)
			{
				return;
			}

			if (!ExceptionType.IsInstanceOfType(filterContext.Exception))
			{
				return;
			}

			// if the request is AJAX return JSON else view.
			if (filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
			{
				filterContext.Result = new JsonResult
				{
					JsonRequestBehavior = JsonRequestBehavior.AllowGet,
					Data = new
					{
						error = true,
						message = filterContext.Exception.Message
					}
				};
			}
			else
			{
				var controllerName = (string)filterContext.RouteData.Values["controller"];
				var actionName = (string)filterContext.RouteData.Values["action"];
				var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);

				filterContext.Result = new ViewResult
				{
					ViewName = View,
					MasterName = Master,
					ViewData = new ViewDataDictionary<HandleErrorInfo>(model),
					TempData = filterContext.Controller.TempData
				};
			}

			_logger.Error(filterContext.Exception.Message, filterContext.Exception);

			filterContext.ExceptionHandled = true;
			filterContext.HttpContext.Response.Clear();
			filterContext.HttpContext.Response.StatusCode = 500;

			filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
		} 
		#endregion
	}
}